import { useEffect, useState, useCallback, useMemo } from "react";
import "./index.less";
import { checkDirection } from "../../utils/gobang/checkDirection.js";
import { Modal } from "antd";
// 定义棋子类型
type Cell = {
  chess: 1 | 2;
  row: number;
  col: number;
};
const GoBang = () => {
  const [border, _setBorder] = useState<any>(
    Array(20).fill(Array(20).fill(""))
  ); //初始化棋盘数据(20列20行)
  const [cellArr, setCellArr] = useState<Cell[]>([]); //已落下的棋子
  const [currentPlayer, setCurrentPlayer] = useState<1 | 2>(2); // 初始化玩家为黑棋先手
  const [isGameOver, setIsGameOver] = useState(false); //游戏结束弹窗
  // 棋子落下的方法
  const cellFall = useCallback(
    (row: number, col: number) => {
      const player = currentPlayer === 1 ? 2 : 1;
      setCurrentPlayer(player); // 切换玩家
      setCellArr([...cellArr, { row, col, chess: player }]);
    },
    [cellArr, currentPlayer]
  );
  // 解决棋子数据更新异步问题
  useEffect(() => {
    if (cellArr.length > 0) {
      // 拿到最新落下的棋子对象
      const lastMove = cellArr[cellArr.length - 1];
      getWinner(lastMove.row, lastMove.col, lastMove.chess);
    }
  }, [cellArr]);

  //  判断输赢(row为行坐标,col为列坐标,currentPlayer为当前玩家)
  const getWinner = (row: number, col: number, currentPlayer: 1 | 2) => {
    const currentCellArr = [...cellArr];
    const currentBorder = [...border.map((row: Array<object>) => [...row])];
    // 将已经下的棋子绑定在棋盘相应位置上
    currentCellArr.forEach(
      (item: any) => (currentBorder[item.row][item.col] = { ...item })
    );
    // 方向向量数组
    const directions = [
      [0, 1], //左右
      [1, 0], //上下
      [1, 1], //左斜
      [-1, 1], //右斜
    ];
    // 遍历8个方向(判断胜利条件(连成的棋子个数大于等于5))
    for (const [dx, dy] of directions) {
      if (checkDirection(row, col, dx, dy, currentBorder, currentPlayer)) {
        // 显示游戏结束弹窗
        setIsGameOver(true);
        return;
      }
    }
  };
  // 缓存计算结果
  const getWinnerName = useMemo((): string => {
    return (currentPlayer === 1 ? "黑棋" : "白棋") + "获胜";
  }, [isGameOver]);
  // 游戏结束弹窗
  // 再来一把
  const gameOverHandleOk = (): void => {
    // 清空棋盘
    setCellArr([]);
    setIsGameOver(false);
  };
  return (
    <>
      <div className="chessboard">
        {border.map((_row: number, rowIndex: number) => (
          <div className="chessboard-row" key={rowIndex}>
            {border.map((_col: number, colIndex: number) => (
              <div className="chessboard-col" key={colIndex}>
                <div className="chessboard-cell">
                  {/* 渲染不同类型棋子 */}
                  {/* 如果cellArr能找到相应棋子 */}
                  {cellArr.find(
                    (item) => item.row === rowIndex && item.col === colIndex
                  ) ? (
                    cellArr.find(
                      (item) => item.row === rowIndex && item.col === colIndex
                    )!.chess === 1 ? (
                      <div className="chessboard-cell-black"></div>
                    ) : (
                      <div className="chessboard-cell-white"></div>
                    )
                  ) : (
                    <div
                      className="chessboard-cell-click"
                      onClick={() => cellFall(rowIndex, colIndex)}
                    ></div>
                  )}
                </div>
              </div>
            ))}
          </div>
        ))}
      </div>

      {/* 游戏结束弹窗 */}
      <Modal
        title="游戏结束"
        open={isGameOver}
        onOk={gameOverHandleOk}
        cancelButtonProps={{ style: { display: "none" } }}
        okText="再来一把"
      >
        <p>{getWinnerName}</p>
      </Modal>
    </>
  );
};
export default GoBang;
